//
// Created by ziya on 22-9-14.
//

#ifndef ZIYA_ELFREADER_FINAL_ELF_H
#define ZIYA_ELFREADER_FINAL_ELF_H

#include "types.h"

#define EI_NIDENT 16

/**=======================================
 *  32位\64位都可用
 */
typedef struct elf_ident {
    uint        e_magic;
    u_char      e_class;
    u_char      e_data;
    u_char      e_version;
    u_char      e_osabi;
    u_char      e_abiversion;
    u_char      e_pad[7];
} __attribute__((packed)) Elf_Ident;


/**=======================================
 *  64位可用
 */
typedef struct elf64_hdr {
    Elf_Ident   e_ident;	            // 16B
    Elf64_Half  e_type;                 // 2B
    Elf64_Half  e_machine;              // 2B
    Elf64_Word  e_version;              // 4B
    Elf64_Addr  e_entry;		        // 8B
    Elf64_Off   e_phoff;                // 8B   程序头表的偏移
    Elf64_Off   e_shoff;		        // 8B   节表的偏移
    Elf64_Word  e_flags;                // 4B
    Elf64_Half  e_ehsize;               // 2B   文件头的大小
    Elf64_Half  e_phentsize;            // 2B   程序头表每项大小
    Elf64_Half  e_phnum;                // 2B   程序头表item的数量
    Elf64_Half  e_shentsize;            // 2B   节表每项大小
    Elf64_Half  e_shnum;                // 2B   节表item的数量
    Elf64_Half  e_shstrndx;             // 2B   字符串表在节表中的索引
} __attribute__((packed)) Elf64_Ehdr;

typedef struct elf64_shdr {
    Elf64_Word sh_name;		    /* 4B Section name, index in string tbl */
    Elf64_Word sh_type;		    /* 4B Type of section */
    Elf64_Xword sh_flags;		/* 8B Miscellaneous section attributes */
    Elf64_Addr sh_addr;		    /* 8B Section virtual addr at execution */
    Elf64_Off sh_offset;		/* 8B Section file offset */
    Elf64_Xword sh_size;		/* 8B Size of section in bytes */
    Elf64_Word sh_link;		    /* 4B Index of another section */
    Elf64_Word sh_info;		    /* 4B Additional section information */
    Elf64_Xword sh_addralign;	/* 8B Section alignment */
    Elf64_Xword sh_entsize;	    /* 8B Entry size if section holds table */
} __attribute__((packed)) Elf64_Shdr;

typedef struct elf64_sym {
    Elf64_Word st_name;		    /* 4B Symbol name, index in string tbl */
    unsigned char	st_info;	/* 1B Type and binding attributes */
    unsigned char	st_other;	/* 1B No defined meaning, 0 */
    Elf64_Half st_shndx;		/* 2B Associated section index */
    Elf64_Addr st_value;		/* 8B Value of the symbol */
    Elf64_Xword st_size;		/* 8B Associated symbol size */
} __attribute__((packed)) Elf64_Sym;

typedef struct elf64_dyn {
    Elf64_Xword d_tag;          // 8B
    union {
        Elf64_Xword     d_val;  // d_tag如果是基数用这个属性(不是绝对)
        Elf64_Addr      d_ptr;  // d_tag如果是偶数用这个属性(不是绝对)
    } d_un;
} __attribute__((packed)) Elf64_Dyn;

typedef struct elf64_phdr {
    Elf64_Word p_type;      // 4B
    Elf64_Word p_flags;     // 4B
    Elf64_Off p_offset;	    /* 8B Segment file offset */
    Elf64_Addr p_vaddr;	    /* 8B Segment virtual address */
    Elf64_Addr p_paddr;	    /* 8B Segment physical address */
    Elf64_Xword p_filesz;	/* 8B Segment size in file */
    Elf64_Xword p_memsz;	/* 8B Segment size in memory */
    Elf64_Xword p_align;	/* 8B Segment alignment, file & memory */
} __attribute__((packed)) Elf64_Phdr;


/**=======================================
 *  32位可用
 */
typedef struct elf32_hdr{
    Elf_Ident 	    e_ident;                // 16B
    Elf32_Half	    e_type;                 // 2B
    Elf32_Half	    e_machine;              // 2B
    Elf32_Word	    e_version;              // 4B
    Elf32_Addr	    e_entry;                /* 4B Entry point */
    Elf32_Off	    e_phoff;                // 4B
    Elf32_Off	    e_shoff;                // 4B
    Elf32_Word	    e_flags;                // 4B
    Elf32_Half	    e_ehsize;               // 2B
    Elf32_Half	    e_phentsize;            // 2B
    Elf32_Half	    e_phnum;                // 2B
    Elf32_Half	    e_shentsize;            // 2B
    Elf32_Half	    e_shnum;                // 2B
    Elf32_Half	    e_shstrndx;             // 2B
} __attribute__((packed)) Elf32_Ehdr;

typedef struct elf32_shdr {
    Elf32_Word	sh_name;
    Elf32_Word	sh_type;
    Elf32_Word	sh_flags;
    Elf32_Addr	sh_addr;
    Elf32_Off	sh_offset;
    Elf32_Word	sh_size;
    Elf32_Word	sh_link;
    Elf32_Word	sh_info;
    Elf32_Word	sh_addralign;
    Elf32_Word	sh_entsize;
} __attribute__((packed)) Elf32_Shdr;

typedef struct elf32_sym{
    Elf32_Word	st_name;            // 4B
    Elf32_Addr	st_value;           // 4B
    Elf32_Word	st_size;            // 4B
    unsigned char	st_info;        // 1B
    unsigned char	st_other;       // 1B
    Elf32_Half	st_shndx;           // 2B
} __attribute__((packed)) Elf32_Sym;

typedef struct elf32_dyn {
    Elf32_Sword d_tag;
    union {
        Elf32_Word      d_val;
        Elf32_Addr      d_ptr;
        Elf32_Off       d_off;
    } d_un;
} __attribute__((packed)) Elf32_Dyn;

typedef struct elf32_phdr {
    Elf32_Word p_type;      // 4B
    Elf32_Off p_offset;     // 4B
    Elf32_Addr p_vaddr;     // 4B
    Elf32_Addr p_paddr;     // 4B
    Elf32_Word p_filesz;    // 4B
    Elf32_Word p_memsz;     // 4B
    Elf32_Word p_flags;     // 4B
    Elf32_Word p_align;     // 4B
} __attribute__((packed)) Elf32_Phdr;


/**=======================================
 *  32位\64位都可用
 */
typedef struct elf {
    u_char      e_type;                 // 类型: 32位 64位
    union {
        Elf64_Ehdr* elf64;
        Elf32_Ehdr* elf32;
    } e_elf;

    u_char*     e_shstring_table;       // 该elf文件的字符串表, 保存各section的名字

    union {
        Elf64_Shdr* shdr64;
        Elf32_Shdr* shdr32;
    } e_shdr;

    u_char*     e_code;                 // 存储代码 .text段的内容

    union {
        Elf64_Sym*  sym64;              // 符号表
        Elf32_Sym*  sym32;
    } e_sym;

    u_char*     e_string_table;         // 保存程序中用到的符合名字,比如函数名\变量名
    u_char*     e_interp;               // 动态链接器

    union {
        Elf64_Dyn* dyn64;               // .dynamic段的数据    readelf -d 可查看
        Elf32_Dyn* dyn32;
    } e_dyn;

    union {                             // 程序头
        Elf64_Phdr *phdr64;
        Elf32_Phdr *phdr32;
    } e_phdr;
} __attribute__((packed)) elf_t;

#endif //ZIYA_ELFREADER_FINAL_ELF_H
